package com.small.nacos.naming.core;

import com.alibaba.nacos.common.utils.CollectionUtils;
import com.small.nacos.core.cluster.ServerMemberManager;
import com.small.nacos.sys.env.EnvUtil;
import org.springframework.stereotype.Component;

import javax.annotation.PostConstruct;
import java.util.ArrayList;
import java.util.List;

/**
 * @Author zhoujin
 * @Date 2022/10/31 19:50
 */
@Component("distroMapper")
public class DistroMapper {

    private volatile List<String> healthyList = new ArrayList<>();

    private final ServerMemberManager memberManager;

    public DistroMapper(ServerMemberManager memberManager) {
        this.memberManager = memberManager;
    }

    @PostConstruct
    public void init() {
        this.healthyList = memberManager.allMembers();
    }

    public boolean responsible(String groupedServiceName) {
        if (healthyList.size() == 0) {
            return true;
        }

        if (EnvUtil.getStandaloneMode()) {
            return true;
        }

        String localAddress = EnvUtil.getLocalAddress();
        int i = healthyList.indexOf(localAddress);
        int index = distroHash(groupedServiceName) % healthyList.size();
        return i == index;
    }

    public String mapSrv(String groupedServiceName) {
        final List<String> servers = healthyList;

        if (CollectionUtils.isEmpty(servers)) {
            return EnvUtil.getLocalAddress();
        }

        try {
            int index = distroHash(groupedServiceName) % servers.size();
            return servers.get(index);
        } catch (Throwable e) {
            return EnvUtil.getLocalAddress();
        }
    }

    private int distroHash(String serviceName) {
        return Math.abs(serviceName.hashCode() % Integer.MAX_VALUE);
    }


}
